// import com.alibaba.druid.sql.SQLUtils;
// import com.alibaba.druid.sql.ast.SQLName;
// import com.alibaba.druid.sql.ast.statement.SQLSelect;
// import com.alibaba.druid.sql.ast.statement.SQLSubqueryTableSource;
// import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
// import com.alibaba.druid.sql.visitor.SQLASTVisitor;

#include "OracleSelectSubqueryTableSource.h"
#include "../../../../SQLUtils.h"
#include "../../../../ast/SQLName.h"
#include "../../../../ast/statement/SQLSelect.h"
#include "../../visitor/OracleASTVisitor.h"
#include "../../../../visitor/SQLASTVisitor.h"
#include "../../../../../utils/listTran.h"

OracleSelectSubqueryTableSource::OracleSelectSubqueryTableSource()
{
}

OracleSelectSubqueryTableSource::OracleSelectSubqueryTableSource(string_ptr alias)
    : SQLSubqueryTableSource(alias)
{
}

OracleSelectSubqueryTableSource::OracleSelectSubqueryTableSource(SQLSelect_ptr select, string_ptr alias)
    : SQLSubqueryTableSource(select, alias)
{
}

OracleSelectSubqueryTableSource::OracleSelectSubqueryTableSource(SQLSelect_ptr select)
    : SQLSubqueryTableSource(select)
{
}

// @Override
void OracleSelectSubqueryTableSource::accept0(SQLASTVisitor_ptr visitor)
{
  this->accept0(std::dynamic_pointer_cast<OracleASTVisitor>(visitor));
}

void OracleSelectSubqueryTableSource::accept0(OracleASTVisitor_ptr visitor)
{
  if (visitor->visit(SharedObject(OracleSelectSubqueryTableSource)))
  {
    SQLObject_list_ptr tmp1 = ListTran::tran_class<SQLHint, SQLObject>(this->getHints());
    acceptChild(visitor, tmp1);
    acceptChild(visitor, this->select);
    acceptChild(visitor, this->pivot);
    acceptChild(visitor, this->unpivot);
    acceptChild(visitor, this->flashback);
  }
  visitor->endVisit(SharedObject(OracleSelectSubqueryTableSource));
}

string_ptr OracleSelectSubqueryTableSource::toString()
{
  return SQLUtils::toOracleString(SharedObject(OracleSelectSubqueryTableSource));
}

SQLObject_ptr OracleSelectSubqueryTableSource::clone()
{
  SQLObject_ptr clone_tmp = std::shared_ptr<OracleSelectSubqueryTableSource>(new OracleSelectSubqueryTableSource());
  std::shared_ptr<OracleSelectSubqueryTableSource> x = std::dynamic_pointer_cast<OracleSelectSubqueryTableSource>(clone_tmp);
  // OracleSelectSubqueryTableSource x = new OracleSelectSubqueryTableSource();
  cloneTo(x);

  if (pivot != nullptr)
  {
    setParent(pivot->clone());
  }

  if (unpivot != nullptr)
  {
    x->setUnpivot(std::dynamic_pointer_cast<SQLUnpivot>(unpivot->clone()));
  }

  return x;
}

void OracleSelectSubqueryTableSource::cloneTo(OracleSelectSubqueryTableSource_ptr x)
{
  x->alias = alias;

  if (this->getPivot() != nullptr)
  {
    x->setPivot(this->getPivot());
  }

  if (select != nullptr)
  {
    x->select = std::dynamic_pointer_cast<SQLSelect>(select->clone());
    x->select->setParent(x);
  }

  for (SQLName_ptr column : *columns)
  {
    SQLName_ptr c2 = std::dynamic_pointer_cast<SQLName>(column->clone());
    c2->setParent(x);
    x->columns->push_back(c2);
  }
}
